/**
 * Copyright (C) 2010 - 2013 Harry Glasgow
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.jaden.engine;

import com.googlecode.jaden.common.other.JadenException;

public class Trainer {

    private DataSet dataSet;
    private Model model;

    public Trainer(DataSet dataSet, Model model) {
        this.dataSet = dataSet;
        this.model = model;
    }

    public double train() throws JadenException {
        double mse = 0;
        for (int i = 0; i < dataSet.getTrainingInputValues().length; i++) {
            String[] inputs = dataSet.getTrainingInputValues()[i];
            String target = dataSet.getTrainingOutputValues()[i];
            String actual = model.forward(inputs);
            double diff;
            if (model.isCategoricalOutputType()) {
                diff = actual.equals(target) ? 0 : 1;
                mse += diff;
            } else {
                diff = Double.parseDouble(actual) - Double.parseDouble(target);
                mse += diff * diff;
            }
            model.backwards(target, actual);
        }
        return Math.sqrt(mse / dataSet.getTrainingInputValues().length);
    }

    public double validate() throws JadenException {
        double mse = 0;
        for (int i = 0; i < dataSet.getValidationInputValues().length; i++) {
            String[] inputs = dataSet.getValidationInputValues()[i];
            String output = dataSet.getValidationOutputValues()[i];
            String result = model.forward(inputs);
            double diff;
            if (model.isCategoricalOutputType()) {
                diff = result.equals(output) ? 0 : 1;
                mse += diff;
            } else {
                diff = Double.parseDouble(result) - Double.parseDouble(output);
                mse += diff * diff;
            }
        }
        return Math.sqrt(mse / dataSet.getValidationInputValues().length);
    }
}
